#### 16.21.1 `define_subst` Example

To illustrate how `define_subst` works, let us examine a simple template transformation.

Suppose there are two kinds of instructions: one that touches flags and the other that does not. The instructions of the second type could be generated with the following `define_subst`:

         (define_subst "add_clobber_subst"
           [(set (match_operand:SI 0 "" "")
                 (match_operand:SI 1 "" ""))]
           ""
           [(set (match_dup 0)
                 (match_dup 1))
            (clobber (reg:CC FLAGS_REG))]

This `define_subst` can be applied to any RTL pattern containing `set` of mode SI and generates a copy with clobber when it is applied.

Assume there is an RTL template for a `max` instruction to be used in `define_subst` mentioned above:

         (define_insn "maxsi"
           [(set (match_operand:SI 0 "register_operand" "=r")
                 (max:SI
                   (match_operand:SI 1 "register_operand" "r")
                   (match_operand:SI 2 "register_operand" "r")))]
           ""
           "max\t{%2, %1, %0|%0, %1, %2}"
          [...])

To mark the RTL template for `define_subst` application, subst-attributes are used. They should be declared in advance:

         (define_subst_attr "add_clobber_name" "add_clobber_subst" "_noclobber" "_clobber")

Here ``add_clobber_name`' is the attribute name, ``add_clobber_subst`' is the name of the corresponding `define_subst`, the third argument (``_noclobber`') is the attribute value that would be substituted into the unchanged version of the source RTL template, and the last argument (``_clobber`') is the value that would be substituted into the second, transformed, version of the RTL template.

Once the subst-attribute has been defined, it should be used in RTL templates which need to be processed by the `define_subst`. So, the original RTL template should be changed:

         (define_insn "maxsi<add_clobber_name>"
           [(set (match_operand:SI 0 "register_operand" "=r")
                 (max:SI
                   (match_operand:SI 1 "register_operand" "r")
                   (match_operand:SI 2 "register_operand" "r")))]
           ""
           "max\t{%2, %1, %0|%0, %1, %2}"
          [...])

The result of the `define_subst` usage would look like the following:

         (define_insn "maxsi_noclobber"
           [(set (match_operand:SI 0 "register_operand" "=r")
                 (max:SI
                   (match_operand:SI 1 "register_operand" "r")
                   (match_operand:SI 2 "register_operand" "r")))]
           ""
           "max\t{%2, %1, %0|%0, %1, %2}"
          [...])
         (define_insn "maxsi_clobber"
           [(set (match_operand:SI 0 "register_operand" "=r")
                 (max:SI
                   (match_operand:SI 1 "register_operand" "r")
                   (match_operand:SI 2 "register_operand" "r")))
            (clobber (reg:CC FLAGS_REG))]
           ""
           "max\t{%2, %1, %0|%0, %1, %2}"
          [...])